package com.xsf.pay.common.utils;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * RSA分段加密工具类
 *
 */
public class RSAUtilSegment {
    private static final String ALGORITHM = "RSA";

    /**
     * 加密算法
     */
    private static final String CIPHER_DE = "RSA";

    /**
     * 解密算法
     */
    private static final String CIPHER_EN = "RSA";

    /**
     * 密钥长度
     */
    private static final Integer KEY_LENGTH = 1024;

    /**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = 117;

    /**
     * RSA最大解密密文大小
     */
    private static final int MAX_DECRYPT_BLOCK = 128;
    // 密钥长度 1024 bit ；密钥格式：PKCS#8
    // 公钥，用于服务商加密商户数据
    public static String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAjqEsfvGDVPCNbMZ0oyqUYMnwT7IxxWYPdB5guQhkCRPoAyLn+zWzjRMv6q80gKdMmg+JTDTu8MI6UhpNhjo/Lc5XT6MDBHjnNEEHDtOmfsG3JAfCJU91RIvfJSlMahewFgAMnE6LFcY4opqUWiO05h2BCGmcrXTD+W3jmlfFOwIDAQAB";

    // 私钥，用于国通解密数据
    public static String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMCOoSx+8YNU8I1sxnSjKpRgyfBPsjHFZg90HmC5CGQJE+gDIuf7NbONEy/qrzSAp0yaD4lMNO7wwjpSGk2GOj8tzldPowMEeOc0QQcO06Z+wbckB8IlT3VEi98lKUxqF7AWAAycTosVxjiimpRaI7TmHYEIaZytdMP5beOaV8U7AgMBAAECgYBWiwQ3amqDu1ZOSdg8LeWCQKoiHr+ZDP5c7bSFhkQWKdpPibFTkB1HsJ0yCQlr0HLgw9E9xQl5Zq305le6Bh0A5fLqH27tbqndqOlBClu0Ck2y54ajszzcTDSNETIcaCccZJwKJE0oH+rXhNme4YPIqbF6TKGxa7Dp8CUavEfoaQJBAPIgcfqMjBl1Su/UcHpzOcl1309RLdIGzEkNkZjsQihkc+F4mIe2fJRlv0gdD3CFuPQPzhNV2DyZ9/l3YuAtcBUCQQDLlxblOPqBt6M7G6E/Qc1PoyUGP5pvswKLfaqFIKHEuXq7dx24svYDSyaSfs7N3nRBBU/k0OWIn0zLalcrzmQPAkAa3NyoZoV4oZnBx/j+rOABaPFwlFoYDicGB9padAPXBWYR4tZRYD6sHCm/r3GyEzP05/f+Dy0hdBed9s/ifUgNAkEAgvkLKKHUPnkWEKOAw4Igg9gPrIpkXvGJdJV+irBogXdVZp6Fx1mR/KJvCRV9E2HF5kJ1mF1vHMpmjAI4XB0lrwJBAJGbVsqvna0jdfHwabS1mlq3060QNgQCEUeeNVe9LcIMH5sGqtLJyfLJyiRutoaqJQGtXTk1mzEuqkitj8c4VXs=";
    /**
     * 公钥加密
     *
     * @param data 待加密的数据
     * @param publicKey 公钥
     * @return byte[]
     */
    public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
        // 得到公钥
        byte[] keyBytes = Base64.decodeBase64(publicKey.getBytes());
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        Key key = keyFactory.generatePublic(x509EncodedKeySpec);
        // 加密数据，分段加密
        Cipher cipher = Cipher.getInstance(CIPHER_EN);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        int inputLength = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offset = 0;
        byte[] cache;
        int i = 0;
        while (inputLength - offset > 0) {
            if (inputLength - offset > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offset, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offset, inputLength - offset);
            }
            out.write(cache, 0, cache.length);
            i++;
            offset = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }

    /**
     * 公钥加密
     *
     * @param data 待加密的数据
     * @param publicKey 公钥
     * @return byte[]
     */
    public static String encryptByPublicKeyMechacct(byte[] data, String publicKey) throws Exception {
        // 得到公钥
        byte[] keyBytes = Base64.decodeBase64(publicKey.getBytes());
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        Key key = keyFactory.generatePublic(x509EncodedKeySpec);
        // 加密数据，分段加密
        Cipher cipher = Cipher.getInstance(CIPHER_EN);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        int inputLength = data.length;
        int offset = 0;
        byte[] cache;
        int i = 0;

        String encryptedDataString = "";
        while (inputLength - offset > 0) {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            if (inputLength - offset > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offset, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offset, inputLength - offset);
            }
            out.write(cache, 0, cache.length);
            byte[] encryptedData = out.toByteArray();
            out.close();

            String dataString = new String(Base64.encodeBase64(encryptedData), StandardCharsets.UTF_8);
            encryptedDataString += dataString;
            if (inputLength - offset > MAX_ENCRYPT_BLOCK) {
                encryptedDataString += "|";
            }

            i++;
            offset = i * MAX_ENCRYPT_BLOCK;
        }

        return encryptedDataString;
    }

    /**
     * 私钥解密
     *
     * @param data 加密后的数据
     * @param privateKey 私钥
     * @return byte[]
     */
    public static byte[] decryptByPrivateKey(byte[] data, String privateKey) throws Exception {
        // 得到私钥
        byte[] keyBytes = Base64.decodeBase64(privateKey.getBytes());
        PKCS8EncodedKeySpec pKCS8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        Key key = keyFactory.generatePrivate(pKCS8EncodedKeySpec);
        // 解密数据，分段解密
        Cipher cipher = Cipher.getInstance(CIPHER_DE);
        cipher.init(Cipher.DECRYPT_MODE, key);
        int inputLength = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offset = 0;
        byte[] cache;
        int i = 0;
        byte[] tmp;
        while (inputLength - offset > 0) {
            if (inputLength - offset > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(data, offset, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offset, inputLength - offset);
            }
//            out.write(cache, 0, cache.length);
            out.write(cache);
            i++;
            offset = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }

    public static byte[] decryptRsa2ByPrivateKey(byte[] data, String privateKey) throws Exception {
        // 获取私钥
        byte[] keyBytes = Base64.decodeBase64(privateKey.getBytes());
        PKCS8EncodedKeySpec pKCS8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey key = keyFactory.generatePrivate(pKCS8EncodedKeySpec);

        // 解密数据，分段解密
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);

        int inputLength = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offset = 0;
        byte[] cache;
        int i = 0;

        while (inputLength - offset > 0) {
            if (inputLength - offset > 256) {
                cache = cipher.doFinal(data, offset, 256);
            } else {
                cache = cipher.doFinal(data, offset, inputLength - offset);
            }
            out.write(cache);
            i++;
            offset = i * 256;
        }

        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }

    public static String privateKeyRsa2Decrypt(String content,String privateKey)throws Exception{
        return new String(decryptRsa2ByPrivateKey(Base64.decodeBase64(content.getBytes()), privateKey));
    }

/**
 * wjh
 * 2023/12/19
 * rsa通过私钥解密
*/
    public static String privateKeyDecrypt(String content,String privateKey)throws Exception{
        return new String(decryptByPrivateKey(Base64.decodeBase64(content), privateKey));
    }

	/**
	 * hm
	 * 2022/01/26
	 * rsa通过私钥解密
	*/
    public static String privateKeyDecryptMechacct(String content,String privateKey)throws Exception{
        // hm:长度限制，按|线分割处理
        String[] parts = content.split("\\|");

        String decryptStr = "";
        byte[] decrypBytes = new byte[0];
        for (int i = 0; i < parts.length; i++) {
            String data = parts[i];
            byte[] moreDecrypBytes = decryptByPrivateKey(Base64.decodeBase64(data), privateKey);
            decrypBytes = mergeByteArrays(decrypBytes,moreDecrypBytes);
        }
        decryptStr = new String(decrypBytes,StandardCharsets.UTF_8);
        return decryptStr;
    }

    public static byte[] mergeByteArrays(byte[] originalData, byte[] additionalData) {
        byte[] mergedData = new byte[originalData.length + additionalData.length];
        System.arraycopy(originalData, 0, mergedData, 0, originalData.length);
        System.arraycopy(additionalData, 0, mergedData, originalData.length, additionalData.length);
        return mergedData;
    }


    /**
     * wjh
     * 2023/12/19
     * rsa通过公钥加密
     */
    public static String publicKeyEncrypt(String content,String publicKey)throws Exception {
        return new String(Base64.encodeBase64(RSAUtilSegment.encryptByPublicKey(content.getBytes(), publicKey)));
    }

    /**
     * hm
     * 2024/01/26
     * rsa通过公钥加密
     */
    public static String publicKeyEncryptMechacct(String content,String publicKey)throws Exception {
        return RSAUtilSegment.encryptByPublicKeyMechacct(content.getBytes(), publicKey);
    }

    public static void main(String[] args) throws Exception{
        String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgRpuimNiLh0W/gKib0La7Gl2xUQH8yOonXGo/tMYh1O0/xR6E4wT/24SCdomYsCCbkh3JWi3iBlE9dgc5/01DzGcvr7gExNNAWjGA1V8a/3tHZIGVz8GAS+PGp/Xy8dmLU6mnq2AsuykL7W58hvu3qPWfZ1f/h5vihAqt1SnX+wIDAQAB";
        String message="{\"code\":\"000000\",\"data\":{\"abbreviation\":\"API测试环境\",\"adChannels\":\"\",\"adId\":\"1815205656983547906\",\"adName\":\"温温温半屏小程序\",\"adPic\":\"\",\"adType\":\"6\",\"adUrl\":\"\",\"adUrl1\":\"\",\"advertisersName\":\"温温温广告商\",\"appletAppid\":\"wxde8ac0a21135c07d\",\"appletName\":\"温温温半屏小程序\",\"appletRedirect\":\"/index/pages/h5/mtlm/mtlm?mt=3&lm=MTgxMzEyNTY4NjE2OTkxOTU2MA%3D%3DMTU3%3D%3D%3D%3D&uid=434333&container=meituan_wxmini&lch=cps:x:0:7cb97a14263b079645f79ceae766eb80:0716guo:404:434333\",\"busName\":\"\",\"channelPrikey\":\"\",\"content\":\"\",\"custId\":\"\",\"fundBrand\":\"151b675eb17e2f98c58c1be015df83b7\",\"gdtAdveId\":\"\",\"gdtEntrance\":\"\",\"hyType\":\"\",\"orderNo\":\"\",\"ortherPic\":\"\",\"pageId\":\"\",\"sportGoldImage\":\"\",\"status\":\"0\",\"taskId\":\"1910600085424152578\",\"trafficId\":\"Mad6c578\",\"trafficName\":\"API测试环境11\",\"txamt\":\"\",\"unitPrice\":\"0.00\",\"wordAdUrl\":\"\"},\"msg\":\"操作成功\",\"pager\":null,\"sensitiveData\":null,\"success\":true,\"timestamp\":\"20250415091216\",\"traceId\":\"1daf9a51f0e199ad_46284858405f24bc\"}";
//        //      对返回的参数进行rsa加密
        String encryptStr = RSAUtilSegment.publicKeyEncrypt(Base64.encodeBase64String(message.getBytes()), publicKey);
        System.out.println(encryptStr);
//        String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALYPlnZI6Ch/EinWvgyGB/kC83Wiub1s9bJKkaqfImC/EsW+n8NuiSFhk/02picu896KVVqYhrElTPD+7aG9BRDVs8vpMoYARx71wN+jBv6533Q4ph4qdU6bfEw4q7kpo400wcJrhULDFLv7KRoapDyybYqPlYGTZ4bMBXfQEnRhAgMBAAECgYAh/GLwDcgY1y/C062ClPqkB2L/ULMvo0lyUO1EVpSKTuDoPR+B0f6TVq3TlQILSn6HyncIhHSQWRA15MDjcm+hVhwPwJMiFACu9EJdM9al/ngNQ2KS44NaUi7KFZuVKIs7ETOgs97w+LVNUnn70JZH79bbbymZfGNFjZ0fdR9AAQJBAOajF5tLdGVt/QtrWK4B2RDs2rhUS4bi+YVQ09/te2v9OTKGQFQp+f7h7y4hiKRE6zCTLaDd62U7qdFAIWPuTWECQQDKFPnYvosy6tC0nLntR+b8ev8K4+reXdrvObxNvk8QdsCPYUJnt5bIgNnHelu23LEXaQv+ONl58mdRriv7FocBAkEA4fItEkpdgXC7UhCcE/xjdx1TOPn78+0wndaNevbgzu6ItmKnasykyXr2Iq9fee66qh/Ft68xCT/mIcU98PRogQJAPz7HXzVrXVkuToiKjB+nxDc+YQsp88ROA/b+3xoDprRz2avn24wSzde90PeTgqyZZClFTqA+ODNMcLzhGOlZAQJAC491pwsZlF0LSAmSd6oi6cXP2nGLxmbZLtdPwibcYMX12AhZgJJCGepCu1IGzaS1vAhS+4VFFn5mDcwZtq5Wew==";
//        System.out.println(RSAUtilSegment.privateKeyDecrypt(encryptStr, privateKey));

        String responMessage="TTajN5yvHUjOqgRsv/bBNFfTOswewFEKE6mcgjdCAURD4mor1fZnJV6SjiplkttVK6s8cu4c60thOR3LewzPIjemxWfAQb1LwjXwljHvTxmueRFqH/Cgbd8xhvzrGZmgN8G2H4qN5ilEY4WrejVXWpVJb9ZHo3doPe1oF0mFt4me4OduAdlBBuRC8qqyiItnqJkfJTqg7+kr/YCMyywRHMQhQx3J+b2wQYjE/9ePT/VDUCovtqPrt5614RUXxVFW8ePuw7tB4wU+gohknNrsOo/ZH2XVGtXxv59Vuj0qOxaifHH+t/DM6Yob5AEDeLMdg+ASFw43RFzht6NvRO/+DBXbEG1tEv5mnkdbOxYHKGMPNvouV8P/y4MofdOss4ZcRAlGaWJYIM1g/4/OOZUVHB4XRgq5vLiorbXP0XxX7tMi0lnzmh2Z6zpxNQKKksuOhPVj7/oBP1QZfnKRwa+s8Eo/DxmwPJqoE0JheU5C+Mq4nJLMke92p4YbC7G3HJT3GRo34MDMtM1Gi7u9GT5RC1eEHN7m/YQG2EDFOxxUM8V4KOdDXF11thZg3FJFOTzMbvrnEKR5IAPDmSkhFQNJsG1ekk9QUq53+m1SyRxTVozP2go5EOBRaWxb0D5wfOBYR49HZgAzu5A9SQnYau3HJplGRFUeN/l4BWi6LkVO25hYnI6Had4zdPV4ccDc2Ugq/oJfjGuOON6VpoLMJo2EzMv/X7hOGnDblgzncHUgRXI6d8LLEOSWtdLzx+PIwH16g3fm91tFUor9LupI471AJXzyYgOnpsVk9O8TAY0e8jvTvTuyO+0RLnsSzPMNXwjfHCdYIzk1oXjS3j7uAHVzMAY4peQgc4tmRPIL3Lu9AVy759YORwvpxT6kpkkIlTZVBKDby9tOgyehz1wogKY1Py+OzRcREqGGFxo79umJIyOy1/OGNJXEudsWVJsI0LEQX810XFMJsfzk0mAMVNcEjIYO+3E/F1qi7x/uYGDObqnUG/MvUi9zDTVA2us9+FNwLg7xgyVjET4BfmQ/BnMoHhkkZ3az62UVcIfnBX2RrhaQw+TOTHjxuAc3yRqkEnzbXS2Vfy1QaRSKJQAKLnrYbn6Snv0t12HkK6QpQc+1Dcg7Xxbgb3I/FwkiQIS9eg539MgwThr5dwavKoPNRD4pwSVwd6nJC01TxABrQgO2CtwSkEypKu9CCDvJ3yIwkjcbf0Nn1iyug57aN9pgU/xp541Wu3B2HSCoJaYMdp0fJkcXfNo7VNiuCeiiGiv5KfdYffk3znffC4NLEv8PQTBJAPSBAX1sW6JCHGLviPSvrcsqk9k1s8G6zbrq2gSn8l2YzJNY9kbHbu7v7imtFtUu0YPlv5IoMLjhC7Kk2H76UHTYiOnAOwSQpT7JvNaSvo5BmUhS7kmzcEjmmpX17vqO5nYiylbeyYW5fLRMRC8l7XcExfkedKNc36EEiy/tEm/5ld1++m9q6EciGP/rYhbIJ5uG4dtIemWTMOt2PkEvLRsYCqKiHFHTG9wQPw8kDoJJ";
        String privateRespKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKBGm6KY2IuHRb+AqJvQtrsaXbFRAfzI6idcaj+0xiHU7T/FHoTjBP/bhIJ2iZiwIJuSHclaLeIGUT12Bzn/TUPMZy+vuATE00BaMYDVXxr/e0dkgZXPwYBL48an9fLx2YtTqaerYCy7KQvtbnyG+7eo9Z9nV/+Hm+KECq3VKdf7AgMBAAECgYBXQ/qLflMxLTcBvOiQ5gQIPaPT3rqJS0+KnNvQ0fmrBAclWIt0aTMYqAovCqGCfCtU6SrErhAbZ7smDrSClIoZSoYkLYdc9aStiyVxmoUQziDHCqd14q62itHyxF2fpmoc3BtOqqCLGDf78w+yP9vuCBhnyCYC47O383tFuVCfcQJBAMsrzYeub9fgUN095Q5UvkyGo0E/XGH9VQM4jtYoLn4yE2JLlqCzi/tAuu8pc1QY/CgMnEsRjmkC2UPg8ca83ekCQQDJ83TIgDKm9ZEu8hi19CXvtArtgzSDa9DvLFuueYxgli0xQNU+l9a+uSFBVmGRT/RcDYI0wzH7Dyfyrdym7yRDAkEAjbyJLdarf9alkzLS0SSdfZWP3rztHg81d4HFY/G0PaWBkFlbQ9D+HtIRlzc7lbe4cdgaUOR2jRvHpmsPQK4RwQJAMQX1cnqUUS1JehDw6LKExwR4pqF0DPcOOBEXjGobJpMuE0e+vDwVuCSuqvKyKpkzI2lwEyjTKDPMqb+E0c05iwJAHryFkEaQ+OZIGizE7nCx9ertNsrPtIHxoi7gzusxk0kfcbDfO+Ck4/zDCaBPUTJwDq8c8lg3PtNV3ezly1+tkQ==";
        System.out.println(new String(Base64.decodeBase64(RSAUtilSegment.privateKeyDecrypt(encryptStr, privateRespKey))));
    }
}
